--author: anti
--at:2018-03-07

function table.contains(table, element)
  for _, value in pairs(table) do
    if value == element then
      return true
    end
  end
  return false
end

function verify_uid(uid)
       return true 
end


function ip_check()

        local iputils = require("resty.iputils")
        local redis = require("resty.redis")

        local blocked_ips = {}
        local red = redis:new()
        red:set_timeout(2000) -- 2s

        local ok ,err = red:connect("127.0.0.1",6379)
        if not ok then
                return
        end

        local res, err = red:auth("qD-tq4xEx")
        if not res then
                --ngx.say("failed to authenticate: ", err)
                return
        end

        res , err = red:SMEMBERS("block_ips")
        if not res then
                return
        end

        for i, v in ipairs(res) do
                table.insert(blocked_ips,v)
        end


        local headers = ngx.req.get_headers()
        local client_ip = headers["X-FORWARDED-FOR"] or headers["X-REAL-IP"]

        blocklist = iputils.parse_cidrs(blocked_ips)
        if iputils.ip_in_cidrs(client_ip , blocklist) then
                local url = "https://www.vvic.com/login.html?f=tusou&reurl=//tusou.vvic.com"
                ngx.redirect(url,"302")
        end


        local ip_time_out=60
        local ip_max_count=5

        ip_count , err = red:get("upload-" .. client_ip )
        if ip_count == ngx.null then
                res , err = red:setex("upload-" .. client_ip ,ip_time_out , 1)
        else
                ip_count = ip_count + 1
                ttl , err = red:ttl("upload-" .. client_ip)
                res , err = red:setex("upload-" .. client_ip , ttl, ip_count)

                if ip_count >= ip_max_count then
                        ngx.status = ngx.OK
                        local resp="{\"code\":200,\"result\":true,\"message\":\"\",\"data\":{\"url\":\"/509.html\"},\"md5\":\"9f587448e3752cb59df72f6c98e06d41\",\"city\":\"gz\"}"
                        return ngx.say(resp)
                end
        end

        local ip_time_out2 = 5
        local ip_max_count2 = 2

        local ip_time_out2 = 5
        local ip_max_count2 = 2

        ip_count2 , err = red:get("upload2-" .. client_ip )
        if ip_count2 == ngx.null then
                res , err = red:setex("upload2-" .. client_ip ,ip_time_out2 , 1)
        else
                ip_count2 = ip_count2 + 1
                ttl , err = red:ttl("upload2-" .. client_ip)
                res , err = red:setex("upload2-" .. client_ip , ttl, ip_count2)

                if ip_count2 >= ip_max_count2 then
                        ngx.status = ngx.OK
                        local resp="{\"code\":200,\"result\":true,\"message\":\"\",\"data\":{\"url\":\"/509.html\"},\"md5\":\"9f587448e3752cb59df72f6c98e06d41\",\"city\":\"gz\"}"
                        return ngx.say(resp)
                end
        end

        local ok, err = red:set_keepalive(10000, 100)
        if not ok then
                --ngx.say("failed to set keepalive: ", err)
                return
        end
end

function uid_check(uid)

        if not verify_uid(uid) then  --uid校验失败
                return
        end

        local redis = require("resty.redis")

        local blocked_uids = {}
        local red = redis:new()
        red:set_timeout(2000) -- 2s

        local ok ,err = red:connect("127.0.0.1",6379)
        if not ok then
                return
        end

        local res, err = red:auth("qD-tq4xEx")
        if not res then
                --ngx.say("failed to authenticate: ", err)
                return
        end

        res , err = red:SMEMBERS("block_uids")
        if not res then
                return
        end

        for i, v in ipairs(res) do
                table.insert(blocked_uids,v)
        end


        if table.contains(blocked_uids,uid) then
                ngx.status = ngx.OK
                local resp="{\"code\":200,\"result\":true,\"message\":\"\",\"data\":{\"url\":\"/403.html\"},\"md5\":\"9f587448e3752cb59df72f6c98e06d41\",\"city\":\"gz\"}"
                return ngx.say(resp)
        end

        local uid_time_out=60
        local uid_max_count=5

        uid_count , err = red:get("uid-" .. uid )
        if uid_count == ngx.null then
                res , err = red:setex("uid-" .. uid ,uid_time_out , 1)
        else
                uid_count = uid_count + 1
                ttl , err = red:ttl("uid-" .. uid)
                res , err = red:setex("uid-" .. uid , ttl, uid_count)

                if uid_count >= uid_max_count then
                        ngx.status = ngx.OK
                        local resp="{\"code\":200,\"result\":true,\"message\":\"\",\"data\":{\"url\":\"/509.html\"},\"md5\":\"9f587448e3752cb59df72f6c98e06d41\",\"city\":\"gz\"}"
                        return ngx.say(resp)
                end
        end

        local uid_time_out2 = 5
        local uid_max_count2 = 2

        uid_count2 , err = red:get("uid2-" .. uid )
        if uid_count2 == ngx.null then
                res , err = red:setex("uid2-" .. uid ,uid_time_out2 , 1)
        else
                uid_count2 = uid_count2 + 1
                ttl , err = red:ttl("uid2-" .. uid)
                res , err = red:setex("uid2-" .. uid , ttl, uid_count2)

                if uid_count2 >= uid_max_count2 then
                        ngx.status = ngx.OK
                        local resp="{\"code\":200,\"result\":true,\"message\":\"\",\"data\":{\"url\":\"/509.html\"},\"md5\":\"9f587448e3752cb59df72f6c98e06d41\",\"city\":\"gz\"}"
                        return ngx.say(resp)
                end
        end

        local ok, err = red:set_keepalive(10000, 100)
        if not ok then
                --ngx.say("failed to set keepalive: ", err)
                return
        end
end



local uid = ngx.var.cookie_uid
if not uid then   --未登陆状态


        --ngx.say("not logined , run ip check")
        ip_check()
		

else  --登陆状态
	
	--ngx.say("is_logind,run uid check")
        uid_check(uid)
end
